package cn.mw.cmdb.virtualization.strategy.handler;

import cn.mw.cmdb.util.SeverityUtils;
import cn.mw.cmdb.virtualization.constant.MwVirtualizationConstant;
import cn.mw.cmdb.virtualization.dto.VirtualizationDto;
import cn.mw.cmdb.virtualization.dto.VirtualizationHostDto;
import cn.mw.cmdb.virtualization.enums.UnicloudHostStatusEnum;
import cn.mw.cmdb.virtualization.enums.VirtualizationHostStatusEnum;
import cn.mw.microMonitorCommon.entity.UnitResult;
import cn.mw.microMonitorCommon.enums.UnicloudTypeEnum;
import cn.mw.microMonitorCommon.enums.VcenterTypeEnum;
import cn.mw.microMonitorCommon.util.UnitUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gengjb
 * @description 主机DTO处理
 * @date 2024/7/1 10:05
 */
public class HostDtoHandler {

    public VirtualizationDto handler(List realDatas){
        VirtualizationDto dto = new VirtualizationDto();
        if(CollectionUtils.isEmpty(realDatas)){return dto;}
        Map<String,Object> cpuMap = new HashMap<>();
        Map<String,Object> memoryMap = new HashMap<>();
        Map<String,Object> storeMap = new HashMap<>();
        for (Object realData : realDatas) {
            VirtualizationHostDto hostDto = (VirtualizationHostDto) realData;
            getCpuValue(hostDto,cpuMap);
            getMemoryValue(hostDto,memoryMap);
            getStoreValue(hostDto,storeMap);
            handlerStatusValue(hostDto);
            handlerUpdateTime(hostDto);
        }
        //设置数据
        finalDataHandler(dto,cpuMap,memoryMap,storeMap);
        return dto;
    }

    private void handlerUpdateTime(VirtualizationHostDto hostDto){
        String type = hostDto.getType();
        UnicloudTypeEnum unicloudTypeEnum = UnicloudTypeEnum.getUnicloudTypeEnumByType(type);
        String runTime = hostDto.getRunTime();
        if(unicloudTypeEnum != null){
            if(StringUtils.isNotEmpty(runTime) && !runTime.equals("-1")){
                hostDto.setPowerStatus(0);
            }else{
                hostDto.setPowerStatus(1);
            }
            return;
        }
        if(StringUtils.isNotEmpty(runTime)){
            String[] split = runTime.split("_");
            String lastTime = SeverityUtils.getLastTime(Long.parseLong(split[0]));
            hostDto.setRunTime(lastTime);
            hostDto.setPowerStatus(0);
        }else{
            hostDto.setPowerStatus(1);
        }
    }

    private void finalDataHandler(VirtualizationDto dto,Map<String,Object> cpuMap,Map<String,Object> memoryMap,Map<String,Object> storeMap){
        if(!cpuMap.isEmpty()){
            Double total = (Double) cpuMap.get(MwVirtualizationConstant.TOTAL_KEY);
            Double used = (Double) cpuMap.get(MwVirtualizationConstant.USED_KEY);
            Double free = (Double) cpuMap.get(MwVirtualizationConstant.FREE_KEY);
            String unit = (String) cpuMap.get(MwVirtualizationConstant.UNIT);
            if(total != null && total != 0){
                double value = (used / total) * 100;
                dto.setCpuUsageRate(new BigDecimal(String.valueOf(value)).setScale(2,BigDecimal.ROUND_HALF_UP).toString());
            }
            if(StringUtils.isNotEmpty(unit)){
                UnitResult totalCpuResult = UnitUtil.getConvertedValue(new BigDecimal(total), unit);
                dto.setTotalCpu(totalCpuResult.getValue()+totalCpuResult.getUnits());
                UnitResult usedCpuResult = UnitUtil.getConvertedValue(new BigDecimal(used), unit);
                dto.setUsedCpu(usedCpuResult.getValue()+usedCpuResult.getUnits());
                UnitResult freeCpuResult = UnitUtil.getConvertedValue(new BigDecimal(free), unit);
                dto.setFreeCpu(freeCpuResult.getValue()+freeCpuResult.getUnits());
            }
        }
        if(!memoryMap.isEmpty()){
            Double total = (Double) memoryMap.get(MwVirtualizationConstant.TOTAL_KEY);
            Double used = (Double) memoryMap.get(MwVirtualizationConstant.USED_KEY);
            Double free = (Double) memoryMap.get(MwVirtualizationConstant.FREE_KEY);
            String unit = (String) memoryMap.get(MwVirtualizationConstant.UNIT);
            if(total != null && total != 0){
                double value = (used / total) * 100;
                dto.setMemoryUsageRate(new BigDecimal(String.valueOf(value)).setScale(2,BigDecimal.ROUND_HALF_UP).toString());
            }
            if(StringUtils.isNotEmpty(unit)){
                UnitResult totalCpuResult = UnitUtil.getConvertedValue(new BigDecimal(total), unit);
                dto.setTotalMemory(totalCpuResult.getValue()+totalCpuResult.getUnits());
                UnitResult usedCpuResult = UnitUtil.getConvertedValue(new BigDecimal(used), unit);
                dto.setUsedMemory(usedCpuResult.getValue()+usedCpuResult.getUnits());
                UnitResult freeCpuResult = UnitUtil.getConvertedValue(new BigDecimal(free), unit);
                dto.setFreeMemory(freeCpuResult.getValue()+freeCpuResult.getUnits());
            }
        }
        if(!storeMap.isEmpty()){
            Double total = (Double) storeMap.get(MwVirtualizationConstant.TOTAL_KEY);
            Double used = (Double) storeMap.get(MwVirtualizationConstant.USED_KEY);
            Double free = (Double) storeMap.get(MwVirtualizationConstant.FREE_KEY);
            String unit = (String) storeMap.get(MwVirtualizationConstant.UNIT);
            if(total != null && total != 0){
                double value = (used / total) * 100;
                dto.setStoreUsageRate(new BigDecimal(String.valueOf(value)).setScale(2,BigDecimal.ROUND_HALF_UP).toString());
            }
            if(StringUtils.isNotEmpty(unit)){
                UnitResult totalCpuResult = UnitUtil.getConvertedValue(new BigDecimal(total), unit);
                dto.setTotalStore(totalCpuResult.getValue()+totalCpuResult.getUnits());
                UnitResult usedCpuResult = UnitUtil.getConvertedValue(new BigDecimal(used), unit);
                dto.setUsedStore(usedCpuResult.getValue()+usedCpuResult.getUnits());
                UnitResult freeCpuResult = UnitUtil.getConvertedValue(new BigDecimal(free), unit);
                dto.setFreeStore(freeCpuResult.getValue()+freeCpuResult.getUnits());
            }
        }
    }

    private void handlerStatusValue(VirtualizationHostDto hostDto){
        String type = hostDto.getType();
        if(StringUtils.isEmpty(type)){return;}
        VcenterTypeEnum vcenterTypeEnum = VcenterTypeEnum.getVcenterTypeEnum(type);
        String status = hostDto.getStatus();
        if(vcenterTypeEnum != null && StringUtils.isNotEmpty(status)){
            VirtualizationHostStatusEnum hostStatusEnum = VirtualizationHostStatusEnum.getHostStatusEnum(status);
            if(hostStatusEnum != null){
                hostDto.setStatus(hostStatusEnum.getStatus());
            }
            return;
        }
        UnicloudTypeEnum unicloudTypeEnum = UnicloudTypeEnum.getUnicloudTypeEnumByType(type);
        if(unicloudTypeEnum != null && StringUtils.isNotEmpty(status)){
            UnicloudHostStatusEnum hostStatusEnum = UnicloudHostStatusEnum.getHostStatusEnum(status);
            if(hostStatusEnum != null){
                hostDto.setStatus(hostStatusEnum.getStatus());
            }
        }
    }

    private void getCpuValue(VirtualizationHostDto hostDto,Map<String,Object> realMap){
        String freeCpu = hostDto.getFreeCpu();
        String usedCpu = hostDto.getUsedCpu();
        double cpuValue = 0;
        double usedValue = 0;
        double freeValue = 0;
        String unit = null;
        if(StringUtils.isNotEmpty(freeCpu)){
            String[] split = freeCpu.split("_");
            cpuValue += Double.parseDouble(split[0]);
            freeValue = Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setFreeCpu(result.getValue()+result.getUnits());
            }else{
                hostDto.setFreeCpu(split[0]+split[1]);
            }
            unit = split[1];
        }
        if(StringUtils.isNotEmpty(usedCpu)){
            String[] split = usedCpu.split("_");
            cpuValue += Double.parseDouble(split[0]);
            usedValue = Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setUsedCpu(result.getValue()+result.getUnits());
            }else{
                hostDto.setUsedCpu(split[0]+split[1]);
            }
            unit = split[1];
        }
        if(cpuValue != 0 && usedValue != 0 && StringUtils.isEmpty(hostDto.getCpuUsageRate())){
            hostDto.setCpuUsageRate(new BigDecimal((usedValue / cpuValue) * 100).setScale(2,BigDecimal.ROUND_HALF_UP) + "%");
        }
        if(StringUtils.isNotEmpty(hostDto.getCpuUsageRate()) && hostDto.getCpuUsageRate().contains("_")){
            String[] split = hostDto.getCpuUsageRate().split("_");
            hostDto.setCpuUsageRate(new BigDecimal(split[0]).setScale(2,BigDecimal.ROUND_HALF_UP).toString()+split[1]);
        }
        setMapInfo(realMap,cpuValue,usedValue,freeValue,unit);
    }


    private void getMemoryValue(VirtualizationHostDto hostDto, Map<String,Object> realMap){
        String usedMemory = hostDto.getUsedMemory();
        String memory = hostDto.getTotalMemory();
        double memoryValue = 0;
        double usedValue = 0;
        String unit = null;
        if(StringUtils.isNotEmpty(memory)){
            String[] split = memory.split("_");
            memoryValue += Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setTotalMemory(result.getValue()+result.getUnits());
            }else{
                hostDto.setTotalMemory(split[0]+split[1]);
            }
            unit = split[1];
        }
        if(StringUtils.isNotEmpty(usedMemory)){
            String[] split = usedMemory.split("_");
            usedValue += Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setUsedMemory(result.getValue()+result.getUnits());
            }else{
                hostDto.setUsedMemory(split[0]+split[1]);
            }
            unit = split[1];
        }
        if(memoryValue != 0 && usedValue != 0){
            hostDto.setMemoryUsageRate(new BigDecimal((usedValue / memoryValue) * 100).setScale(2,BigDecimal.ROUND_HALF_UP) + "%");
        }
        if(StringUtils.isNotEmpty(hostDto.getMemoryUsageRate()) && hostDto.getMemoryUsageRate().contains("_")){
            String[] split = hostDto.getMemoryUsageRate().split("_");
            hostDto.setMemoryUsageRate(new BigDecimal(split[0]).setScale(2,BigDecimal.ROUND_HALF_UP).toString()+split[1]);
        }
        setMapInfo(realMap,memoryValue,usedValue,memoryValue - usedValue,unit);
    }

    private void getStoreValue(VirtualizationHostDto hostDto, Map<String,Object> realMap){
        String totalStore = hostDto.getTotalStore();
        String usedStore = hostDto.getUsedStore();
        double storeValue = 0;
        double usedValue = 0;
        String unit = null;
        if(StringUtils.isNotEmpty(totalStore)){
            String[] split = totalStore.split("_");
            storeValue += Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setTotalStore(result.getValue()+result.getUnits());
            }else{
                hostDto.setTotalStore(split[0]+split[1]);
            }
            unit = split[1];
        }
        if(StringUtils.isNotEmpty(usedStore)){
            String[] split = usedStore.split("_");
            usedValue += Double.parseDouble(split[0]);
            //单位转换
            UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(split[0]), split[1]);
            if(result != null){
                hostDto.setUsedStore(result.getValue()+result.getUnits());
            }else{
                hostDto.setUsedStore(split[0]+split[1]);
            }
            unit = split[1];
        }
        setMapInfo(realMap,storeValue,usedValue,storeValue - usedValue,unit);
    }


    private void setMapInfo(Map<String,Object> realMap,double totalValue,double usedValue,double freeValue,String unit){
        if(realMap.containsKey(MwVirtualizationConstant.TOTAL_KEY)){
            Double total = (Double) realMap.get(MwVirtualizationConstant.TOTAL_KEY);
            realMap.put(MwVirtualizationConstant.TOTAL_KEY,total+totalValue);
        }else{
            realMap.put(MwVirtualizationConstant.TOTAL_KEY,totalValue);
        }
        if(realMap.containsKey(MwVirtualizationConstant.USED_KEY)){
            Double used = (Double) realMap.get(MwVirtualizationConstant.USED_KEY);
            realMap.put(MwVirtualizationConstant.USED_KEY,used+usedValue);
        }else{
            realMap.put(MwVirtualizationConstant.USED_KEY,usedValue);
        }
        if(realMap.containsKey(MwVirtualizationConstant.FREE_KEY)){
            Double free = (Double) realMap.get(MwVirtualizationConstant.FREE_KEY);
            realMap.put(MwVirtualizationConstant.FREE_KEY,free+freeValue);
        }else{
            realMap.put(MwVirtualizationConstant.FREE_KEY,freeValue);
        }
        if(StringUtils.isNotEmpty(unit)){
            realMap.put(MwVirtualizationConstant.UNIT,unit);
        }
    }
}
